package com.adaptiveAgingAdmin.security.filter;

import cn.hutool.core.util.ObjectUtil;
import com.adaptiveAgingAdmin.code.Code;
import com.adaptiveAgingAdmin.code.Result;
import com.adaptiveAgingAdmin.domain.Admin;
import com.adaptiveAgingAdmin.utils.GsonUtil;
import com.adaptiveAgingAdmin.utils.JwtUtil;
import com.adaptiveAgingAdmin.utils.RedisUtil;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * token过滤器
 *
 * @author 张涛
 */
public class TokenAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        获取请求头的token
        String token = request.getHeader("Authorization");
        String key;
//        如果有token,解析token并完成信息认证;没有token,则直接放行
        if(StringUtils.hasText(token)){
            try {
                key=RedisUtil.ID_PREFIX+JwtUtil.parseToken(token);
            }catch (TokenExpiredException tokenExpiredException){
                tokenExpiredException.printStackTrace();
                Result.exceptionResponse(response, Code.TOKEN_EXPIRE,null,"token过期");
                return;
            }
            catch (JWTVerificationException jwtVerificationException){
                jwtVerificationException.printStackTrace();
                Result.exceptionResponse(response, Code.TOKEN_INVALID,null,"token非法");
                return;
            }
            catch (Exception e){
                e.printStackTrace();
                Result.exceptionResponse(response, Code.EXCEPTION,null,e.getMessage());
                return;
            }
//            token解析成功,查询redis中存储的信息,并存入SecurityContext中完成认证
            String accessToken = RedisUtil.getHashValue(key,"accessToken");

            if(!token.equals(accessToken)){
                Result.exceptionResponse(response, Code.NOT_LOGIN,null,"用户未登录");
                return;
            }
            String adminJson=RedisUtil.getHashValue(key,"admin");
            Admin admin=GsonUtil.parseJson(adminJson,Admin.class);
            if(ObjectUtil.isNull(admin)){
                Result.exceptionResponse(response, Code.NOT_LOGIN,null,"用户未登录");
                return;
            }
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(admin, null, admin.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        }
        filterChain.doFilter(request, response);
    }
}
